home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tde210.zip / HWIND.C < prev    next >
Text File  |  1992-11-13  |  18KB  |  645 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    hardware independent screen IO module
  10.  * Purpose: This file contains the code to interface the rest of the
  11.  *           editor to the display and input hardware.
  12.  * File:    hwind.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 2, 1989
  16.  * Notes:   This is the only module that is allowed to call the hardware
  17.  *           dependent display IO library.
  18.  *          Typically, functions here check whether any action is
  19.  *           necessary (for example, the cursor may already happen to be
  20.  *           in the required position), call hardware dependent functions
  21.  *           to achieve the required effect, and finally update status
  22.  *           information about the current state of the terminal display.
  23.  *          The idea behind this approach is to keep the hardware
  24.  *           dependent code as small and simple as possible, thus making
  25.  *           porting the code easier.
  26.  */
  27. /*********************  end of original comments   ********************/
  28.  
  29.  
  30. /*
  31.  * Some routines were added to display current editor modes in the lite bar
  32.  * at the bottom of the screen. Other routines were rewritten in assembly.
  33.  * I feel the need for speed.
  34.  *
  35.  * New editor name:  TDE, the Thomson-Davis Editor.
  36.  * Author:           Frank Davis
  37.  * Date:             June 5, 1991, version 1.0
  38.  * Date:             July 29, 1991, version 1.1
  39.  * Date:             October 5, 1991, version 1.2
  40.  * Date:             January 20, 1992, version 1.3
  41.  * Date:             February 17, 1992, version 1.4
  42.  * Date:             April 1, 1992, version 1.5
  43.  * Date:             June 5, 1992, version 2.0
  44.  * Date:             October 31, 1992, version 2.1
  45.  *
  46.  * This modification of Douglas Thomson's code is released into the
  47.  * public domain, Frank Davis.  You may distribute it freely.
  48.  */
  49.  
  50. #include <bios.h>       /* for REGS */
  51. #include <dos.h>        /* for intdos */
  52.  
  53. #include "tdestr.h"
  54. #include "common.h"
  55. #include "tdefunc.h"
  56. #include "define.h"
  57.  
  58.  
  59. /*
  60.  * Name:    get_date
  61.  * Purpose: get system date from DOS
  62.  * Date:    June 5, 1992
  63.  * Passed:  year:  pointer to integer to store year
  64.  *          month: pointer to integer to store month
  65.  *          day:   pointer to integer to store day
  66.  *          day_of_week:  pointer to integer to store dow
  67.  * Notes:   call standard DOS interrupt 0x21, function 0x2a to get the date.
  68.  */
  69. void get_date( int *year, int *month, int *day, int *day_of_week  )
  70. {
  71. union REGS inregs, outregs;
  72.  
  73.    inregs.h.ah = 0x2a;
  74.    intdos( &inregs, &outregs );
  75.    *year        = (int)outregs.x.cx;
  76.    *month       = (int)outregs.h.dh;
  77.    *day         = (int)outregs.h.dl;
  78.    *day_of_week = (int)outregs.h.al;
  79. }
  80.  
  81.  
  82. /*
  83.  * Name:    get_time
  84.  * Purpose: get system time from DOS
  85.  * Date:    June 5, 1992
  86.  * Passed:  hour:  pointer to integer to store hour - system returns 24 hour
  87.  *          minutes:  pointer to integer to store minutes
  88.  *          seconds:  pointer to integer to store seconds
  89.  *          hundredths:  pointer to integer to store hundredths of second
  90.  * Notes:   call standard DOS interrupt 0x21, function 0x2c to get the time.
  91.  */
  92. void get_time( int *hour, int *minutes, int *seconds, int *hundredths  )
  93. {
  94. union REGS inregs, outregs;
  95.  
  96.    inregs.h.ah = 0x2c;
  97.    intdos( &inregs, &outregs );
  98.    *hour       = (int)outregs.h.ch;
  99.    *minutes    = (int)outregs.h.cl;
  100.    *seconds    = (int)outregs.h.dh;
  101.    *hundredths = (int)outregs.h.dl;
  102. }
  103.  
  104.  
  105. /*
  106.  * Name:    xygoto
  107.  * Purpose: To move the cursor to the required column and line.
  108.  * Date:    September 28, 1991
  109.  * Passed:  col:    desired column (0 up to max)
  110.  *          line:   desired line (0 up to max)
  111.  * Notes;   use standard BIOS video interrupt 0x10 to set the set.
  112.  */
  113. void xygoto( int col, int line )
  114. {
  115. union REGS inregs, outregs;
  116.  
  117.    inregs.h.ah = 2;
  118.    inregs.h.bh = 0;
  119.    inregs.h.dh = (unsigned char)line;
  120.    inregs.h.dl = (unsigned char)col;
  121.    int86( 0x10, &inregs, &outregs );
  122. }
  123.  
  124.  
  125. /*
  126.  * Name:    save_screen_line
  127.  * Purpose: To save the characters and attributes of a line on screen.
  128.  * Date:    June 5, 1991
  129.  * Passed:  col:    desired column, usually always zero
  130.  *          line:   line on screen to save (0 up to max)
  131.  *          screen_buffer:  buffer for screen contents, must be 160 chars
  132.  * Notes:   Save the contents of the line on screen where prompt is
  133.  *          to be displayed
  134.  */
  135. void save_screen_line( int col, int line, char *screen_buffer )
  136. {
  137. char far *p;
  138.  
  139.    p = g_display.display_address + line * 160 + col * 2;
  140.    _fmemcpy( screen_buffer, p, 160 );
  141. }
  142.  
  143.  
  144. /*
  145.  * Name:    restore_screen_line
  146.  * Purpose: To restore the characters and attributes of a line on screen.
  147.  * Date:    June 5, 1991
  148.  * Passed:  col:    usually always zero
  149.  *          line:   line to restore (0 up to max)
  150.  *          screen_buffer:  buffer for screen contents
  151.  * Notes:   Restore the contents of the line on screen where the prompt
  152.  *          was displayed
  153.  */
  154. void restore_screen_line( int col, int line, char *screen_buffer )
  155. {
  156. char far *p;
  157.  
  158.    p = g_display.display_address + line * 160 + col * 2;
  159.    _fmemcpy( p, screen_buffer, 160 );
  160. }
  161.  
  162.  
  163. /*
  164.  * Name:    initialize
  165.  * Purpose: To initialize all the screen status info that is not hardware
  166.  *           dependent, and call the hardware initialization routine to
  167.  *           pick up the hardware dependent stuff.
  168.  * Date:    June 5, 1991
  169.  * Returns: [g_status and g_display]: all set up ready to go
  170.  * Notes:   It is assumed that g_status and g_display are all \0's to begin
  171.  *           with (the default if they use static storage). If this may
  172.  *           not be the case, then clear them explicitly here.
  173.  */
  174. void initialize( void )
  175. {
  176.    /*
  177.     * do the hardware initialization first.  this allocates the main
  178.     *  text buffer and sets up other info needed here.
  179.     */
  180.    hw_initialize( );
  181.  
  182.    bm.search_defined = ERROR;
  183.  
  184.    /*
  185.     * the main text buffer must be preceded by a ^Z, so that backward
  186.     *  searches can see the start of the text buffer
  187.     */
  188.    *g_status.start_mem++ = CONTROL_Z;
  189.  
  190.    /*
  191.     * most of the system's text pointers are safer set to the start
  192.     *  of the text buffer - some of these may not be strictly
  193.     *  necessary.
  194.     */
  195.    g_status.temp_end = g_status.start_mem;
  196.    g_status.end_mem = g_status.start_mem;
  197.  
  198.  
  199.    /*
  200.     * initialize the undo buffer similiar to the the main text buffer.
  201.     *   put a ^Z as the first in the undo buffer so that backward
  202.     *   searches can see the start of the undo buffer.
  203.     */
  204.    g_status.top_stack  = (text_ptr)g_status.undo_buffer;
  205.    *g_status.top_stack = CONTROL_Z;
  206.    g_status.top_stack  = nptos( g_status.top_stack ) + 1;
  207.    g_status.bot_stack  = NULL;
  208.    g_status.max_stack  = (text_ptr)&g_status.undo_buffer[UNDO_MAX-1][BUFF_SIZE-1];
  209.  
  210.  
  211.    /*
  212.     * initialize pointers and counters
  213.     */
  214.    g_status.marked = FALSE;
  215.    g_status.marked_file = NULL;
  216.  
  217.    g_status.current_window = NULL;
  218.    g_status.current_file = NULL;
  219.    g_status.window_list = NULL;
  220.    g_status.file_list = NULL;
  221.    g_status.window_count = 0;
  222.    g_status.file_count = 0;
  223.  
  224.    /*
  225.     * set the number of lines from one page that should still be visible
  226.     *  on the next page after page up or page down.
  227.     */
  228.    g_status.overlap = 1;
  229.  
  230.    /*
  231.     * start out with no wrapped error message.
  232.     */
  233.    g_status.wrapped = FALSE;
  234.  
  235.    /*
  236.     * no macro is executing
  237.     */
  238.    g_status.macro_executing = FALSE;
  239.  
  240.    g_status.recording_key = 0;
  241.    connect_macros( );
  242.  
  243.  
  244.    /*
  245.     * clear the screen and show the author's names
  246.     */
  247.    cls( );
  248.    show_credits( );
  249. }
  250.  
  251.  
  252. /*
  253.  * Name:    show_modes
  254.  * Purpose: show current editor modes in lite bar at bottom of screen
  255.  * Date:    June 5, 1991
  256.  */
  257. void show_modes( void )
  258. {
  259. char status_line[MAX_COLS+2];
  260.  
  261.    memset( status_line, ' ', MAX_COLS );
  262.    status_line[MAX_COLS] = '\0';
  263.    s_output( status_line, g_display.mode_line, 0, g_display.mode_color );
  264.    s_output( "F=   W=", g_display.mode_line, 1, g_display.mode_color );
  265.    s_output( "mem=", g_display.mode_line, 11, g_display.mode_color );
  266.    show_window_count( g_status.window_count );
  267.    show_file_count( g_status.file_count );
  268.    show_avail_mem( );
  269.    show_tab_modes( );
  270.    show_indent_mode( );
  271.    show_sync_mode( );
  272.    show_control_z( );
  273.    show_insert_mode( );
  274.    show_search_case( );
  275.    show_wordwrap_mode( );
  276.    show_crlf_mode( );
  277.    show_trailing( );
  278. }
  279.  
  280.  
  281. /*
  282.  * Name:    show_file_count
  283.  * Purpose: show number of open files in lite bar at bottom of screen
  284.  * Passed:  fc:  file count - number of open files
  285.  * Date:    June 5, 1991
  286.  */
  287. void show_file_count( int fc )
  288. {
  289. char status_line[MAX_COLS+2];
  290.  
  291.    s_output( "  ", g_display.mode_line, 3, g_display.mode_color );
  292.    s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3,
  293.              g_display.mode_color );
  294. }
  295.  
  296.  
  297. /*
  298.  * Name:    show_window_count
  299.  * Purpose: show total number of windows in lite bar at bottom of screen
  300.  * Passed:  wc:  window count - visible and hidden.
  301.  * Date:    September 13, 1991
  302.  */
  303. void show_window_count( int wc )
  304. {
  305. char status_line[MAX_COLS+2];
  306.  
  307.    s_output( "  ", g_display.mode_line, 8, g_display.mode_color );
  308.    s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8,
  309.              g_display.mode_color );
  310. }
  311.  
  312.  
  313. /*
  314.  * Name:    show_avail_mem
  315.  * Purpose: show available free memory in lite bar at bottom of screen
  316.  * Date:    June 5, 1991
  317.  */
  318. void show_avail_mem( void )
  319. {
  320. char memory[MAX_COLS+2];
  321. long avail;
  322.  
  323.    avail = ptoul( g_status.max_mem ) - ptoul( g_status.end_mem );
  324.    ltoa( avail, memory, 10 );
  325.    s_output( "        ", g_display.mode_line, 15, g_display.mode_color );
  326.    s_output( memory, g_display.mode_line, 15, g_display.mode_color );
  327. }
  328.  
  329.  
  330. /*
  331.  * Name:    show_tab_modes
  332.  * Purpose: show smart tab mode in lite bar at bottom of screen
  333.  * Date:    October 31, 1992
  334.  */
  335. void show_tab_modes( void )
  336. {
  337. char *blank_tab = "   ";
  338. char ascii_tab[10];
  339.  
  340.    s_output( tabs, g_display.mode_line, 24, g_display.mode_color );
  341.    s_output( mode.smart_tab ? smart : fixed, g_display.mode_line, 29,
  342.              g_display.mode_color );
  343.    s_output( mode.inflate_tabs ? intab : outtab, g_display.mode_line, 30,
  344.              g_display.mode_color );
  345.    s_output( blank_tab, g_display.mode_line, 31, g_display.mode_color );
  346.    s_output( itoa( mode.ptab_size, ascii_tab, 10), g_display.mode_line, 31,
  347.              g_display.mode_color );
  348. }
  349.  
  350.  
  351. /*
  352.  * Name:    show_indent_mode
  353.  * Purpose: show indent mode in lite bar at bottom of screen
  354.  * Date:    June 5, 1991
  355.  */
  356. void show_indent_mode( void )
  357. {
  358.    s_output( mode.indent ? indent : blank, g_display.mode_line, 34,
  359.              g_display.mode_color );
  360. }
  361.  
  362.  
  363. /*
  364.  * Name:    show_search_case
  365.  * Purpose: show search mode in lite bar
  366.  * Date:    June 5, 1991
  367.  */
  368. void show_search_case( void )
  369. {
  370.    s_output( mode.search_case == IGNORE ? ignore : match, g_display.mode_line,
  371.              42, g_display.mode_color );
  372. }
  373.  
  374.  
  375. /*
  376.  * Name:    show_sync_mode
  377.  * Purpose: show sync mode in lite bar
  378.  * Date:    January 15, 1992
  379.  */
  380. void show_sync_mode( void )
  381. {
  382.    s_output( mode.sync ? sync_on : sync_off, g_display.mode_line, 50,
  383.              g_display.mode_color );
  384. }
  385.  
  386.  
  387. /*
  388.  * Name:    show_wordwrap_mode
  389.  * Purpose: display state of word wrap mode
  390.  * Date:    June 5, 1991
  391.  */
  392. void show_wordwrap_mode( void )
  393. {
  394.    s_output( ww_mode[mode.word_wrap], g_display.mode_line, 56,
  395.              g_display.mode_color );
  396. }
  397.  
  398.  
  399. /*
  400.  * Name:    show_crlf_mode
  401.  * Purpose: display state of crlf flag
  402.  * Date:    June 5, 1991
  403.  */
  404. void show_crlf_mode( void )
  405. {
  406.    s_output( mode.crlf == CRLF ? crlf : lf, g_display.mode_line, 60,
  407.              g_display.mode_color );
  408. }
  409.  
  410.  
  411. /*
  412.  * Name:    show_trailing
  413.  * Purpose: show state of trailing flag
  414.  * Date:    June 5, 1991
  415.  */
  416. void show_trailing( void )
  417. {
  418.    c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line,
  419.              g_display.mode_color );
  420. }
  421.  
  422.  
  423. /*
  424.  * Name:    show_control_z
  425.  * Purpose: show state of control z flag
  426.  * Date:    June 5, 1991
  427.  */
  428. void show_control_z( void )
  429. {
  430.    c_output( mode.control_z ? ' ' : 'Z', 77, g_display.mode_line,
  431.              g_display.mode_color );
  432. }
  433.  
  434.  
  435. /*
  436.  * Name:    show_insert_mode
  437.  * Purpose: show insert mode in lite bar
  438.  * Date:    June 5, 1991
  439.  */
  440. void show_insert_mode( void )
  441. {
  442.    c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line,
  443.              g_display.mode_color );
  444. }
  445.  
  446.  
  447. /*
  448.  * Name:    my_scroll_down
  449.  * Purpose: display a portion of a window
  450.  * Date:    June 5, 1991
  451.  * Passed:  window:  pointer to current window
  452.  * Notes:   Using the bios scroll functions causes a slightly noticable
  453.  *            "flicker", even on fast VGA monitors.  This is caused by changing
  454.  *            the high-lited cursor line to text color then calling the bios
  455.  *            function to scroll.  Then, the current line must then be
  456.  *            hilited.
  457.  *          This function assumes that win->cline is the current line.
  458.  */
  459. void my_scroll_down( WINDOW *window )
  460. {
  461. int i;
  462. int curl;
  463. long length;
  464. WINDOW w;              /* scratch window struct for dirty work */
  465. register WINDOW *win;  /* put window pointer in a register */
  466.  
  467.    win = window;
  468.    length = win->file_info->length;
  469.    dup_window_info( &w, win );
  470.    curl = i = win->bottom_line + 1 - win->cline;
  471.    for (; i>0; i--) {
  472.       if (w.cursor) {
  473.          if (w.rline <= length) {
  474.             if (i != curl)
  475.                update_line( &w );
  476.          } else
  477.             show_eof( &w );
  478.          w.cursor = find_next( w.cursor );
  479.       } else
  480.          window_eol_clear( &w, COLOR_TEXT );
  481.       ++w.cline;
  482.       ++w.rline;
  483.    }
  484.    show_curl_line( win );
  485. }
  486.  
  487.  
  488. /*
  489.  * Name:    combine_strings
  490.  * Purpose: stick 3 strings together
  491.  * Date:    June 5, 1991
  492.  * Passed:  buff:    buffer to hold concatenation of 3 strings
  493.  *          s1:  pointer to string 1
  494.  *          s2:  pointer to string 2
  495.  *          s3:  pointer to string 3
  496.  */
  497. void combine_strings( char *buff, char *s1, char *s2, char *s3 )
  498. {
  499.    strcpy( buff, s1 );
  500.    strcat( buff, s2 );
  501.    strcat( buff, s3 );
  502. }
  503.  
  504.  
  505. /*
  506.  * Name:    make_ruler
  507.  * Purpose: make ruler with tabs, tens, margins, etc...
  508.  * Date:    June 5, 1991
  509.  * Passed:  window:  pointer to current window
  510.  */
  511. void make_ruler( WINDOW *window )
  512. {
  513. register WINDOW *win;
  514. char num[20];
  515. register char *p;
  516. int len;
  517. int col;
  518. int i;
  519. int mod;
  520.  
  521.    win = window;
  522.  
  523.    /*
  524.     * need to have a least two lines in a window when we display a ruler.
  525.     */
  526.    if (win->bottom_line - win->top_line < 1)
  527.       win->ruler = FALSE;
  528.    if (win->ruler) {
  529.  
  530.       /*
  531.        * find the width of the window and fill the ruler with dots.
  532.        */
  533.       len = win->end_col + 1 - win->start_col;
  534.       memset( win->ruler_line, '.', len );
  535.       win->ruler_line[len] = '\0';
  536.       col = win->bcol+1;
  537.       for (p=win->ruler_line; *p; col++, p++) {
  538.  
  539.          /*
  540.           * put a tens digit in the tens column
  541.           */
  542.          mod = col % 10;
  543.          if (mod == 0) {
  544.             itoa( col/10, num, 10 );
  545.  
  546.             /*
  547.              * let the margin chars have precidence over tens digit
  548.              */
  549.             for (i=0; num[i] && *p; col++, i++) {
  550.                if (col == mode.left_margin+1)
  551.                   *p = '┤';
  552.                else if (col == mode.right_margin+1)
  553.                   *p = '├';
  554.                else if (col == mode.parg_margin+1)
  555.                   *p = '';
  556.                else
  557.                   *p = num[i];
  558.                p++;
  559.             }
  560.  
  561.             /*
  562.              * we may have come to the end of the ruler in the for loop.
  563.              */
  564.             if (*p == '\0')
  565.                break;
  566.          } else if (mod == 5)
  567.             *p = '';
  568.          if (col == mode.parg_margin+1)
  569.             *p = '';
  570.          if (col == mode.left_margin+1)
  571.             *p = '┤';
  572.          else if (col == mode.right_margin+1)
  573.             *p = '├';
  574.       }
  575.    }
  576. }
  577.  
  578.  
  579. /*
  580.  * Name:    show_ruler
  581.  * Purpose: show ruler with tens, margins, etc...
  582.  * Date:    June 5, 1991
  583.  * Passed:  window:  pointer to current window
  584.  */
  585. void show_ruler( WINDOW *window )
  586. {
  587.    if (window->ruler && window->visible)
  588.       s_output( window->ruler_line, window->top_line, window->start_col,
  589.                 g_display.ruler_color );
  590. }
  591.  
  592.  
  593. /*
  594.  * Name:    show_ruler_char
  595.  * Purpose: show ruler character under ruler pointer
  596.  * Date:    June 5, 1991
  597.  * Passed:  window:  pointer to current window
  598.  */
  599. void show_ruler_char( WINDOW *window )
  600. {
  601. register WINDOW *win;
  602. char c;
  603.  
  604.    win = window;
  605.    if (win->ruler && win->visible) {
  606.       c = win->ruler_line[win->ccol - win->start_col];
  607.       c_output( c, win->ccol, win->top_line, g_display.ruler_color );
  608.    }
  609. }
  610.  
  611.  
  612. /*
  613.  * Name:    show_ruler_pointer
  614.  * Purpose: show ruler pointer
  615.  * Date:    June 5, 1991
  616.  * Passed:  window:  pointer to current window
  617.  */
  618. void show_ruler_pointer( WINDOW *window )
  619. {
  620.    if (window->ruler && window->visible)
  621.       c_output( RULER_CHAR, window->ccol, window->top_line,
  622.                 g_display.ruler_pointer );
  623. }
  624.  
  625.  
  626. /*
  627.  * Name:    show_all_rulers
  628.  * Purpose: make and show all rulers in all visible windows
  629.  * Date:    June 5, 1991
  630.  */
  631. void show_all_rulers( void )
  632. {
  633. register WINDOW *wp;
  634.  
  635.    wp = g_status.window_list;
  636.    while (wp != NULL) {
  637.       make_ruler( wp );
  638.       if (wp->visible) {
  639.          show_ruler( wp );
  640.          show_ruler_pointer( wp );
  641.       }
  642.       wp = wp->next;
  643.    }
  644. }
  645.